﻿using System.Windows.Media;
using System.Windows.Shapes;

namespace System.Windows.Controls
{
    internal class CenteredEllipse : Shape
    {
        // Dependency properties
        public static readonly DependencyProperty CenterProperty =
            EllipseGeometry.CenterProperty.AddOwner(
                typeof (CenteredEllipse),
                new FrameworkPropertyMetadata(new Point(0, 0),
                                              EllipsePropertyChanged));

        public static readonly DependencyProperty RadiusXProperty =
            EllipseGeometry.RadiusXProperty.AddOwner(
                typeof (CenteredEllipse),
                new FrameworkPropertyMetadata(0.0,
                                              EllipsePropertyChanged));

        public static readonly DependencyProperty RadiusYProperty =
            EllipseGeometry.RadiusYProperty.AddOwner(
                typeof (CenteredEllipse),
                new FrameworkPropertyMetadata(0.0,
                                              EllipsePropertyChanged));

        public static readonly DependencyProperty RotationAngleProperty =
            ArcSegment.RotationAngleProperty.AddOwner(
                typeof (CenteredEllipse),
                new FrameworkPropertyMetadata(0.0,
                                              TransformPropertyChanged));

        private readonly EllipseGeometry _elipGeo = new EllipseGeometry();
        private readonly RotateTransform _xform = new RotateTransform();

        public CenteredEllipse()
        {
            _elipGeo.Transform = _xform;
        }

        // Public CLR properties
        public Point Center
        {
            set { SetValue(CenterProperty, value); }
            get { return (Point) GetValue(CenterProperty); }
        }

        public double RadiusX
        {
            set { SetValue(RadiusXProperty, value); }
            get { return (double) GetValue(RadiusXProperty); }
        }

        public double RadiusY
        {
            set { SetValue(RadiusYProperty, value); }
            get { return (double) GetValue(RadiusYProperty); }
        }

        public double RotationAngle
        {
            set { SetValue(RotationAngleProperty, value); }
            get { return (double) GetValue(RotationAngleProperty); }
        }

        // Required DefiningGeometry override
        protected override Geometry DefiningGeometry
        {
            get { return _elipGeo; }
        }

        private static void EllipsePropertyChanged(DependencyObject obj,
                                                   DependencyPropertyChangedEventArgs args)
        {
            (obj as CenteredEllipse).EllipsePropertyChanged(args);
        }

        private static void TransformPropertyChanged(DependencyObject obj,
                                                     DependencyPropertyChangedEventArgs args)
        {
            (obj as CenteredEllipse).TransformPropertyChanged(args);
        }

        private void EllipsePropertyChanged(DependencyPropertyChangedEventArgs args)
        {
            _elipGeo.Center = Center;
            _elipGeo.RadiusX = RadiusX;
            _elipGeo.RadiusY = RadiusY;
            InvalidateMeasure();
        }

        private void TransformPropertyChanged(DependencyPropertyChangedEventArgs args)
        {
            _xform.Angle = RotationAngle;
            _xform.CenterX = Center.X;
            _xform.CenterY = Center.Y;
            InvalidateMeasure();
        }
    }
}